/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use attestation::strategy::strategy_impl::default::DefaultAttestationStrategy;
use attestation::strategy::attestation_strategy::AttestationStrategy;
use attestation::entities::attest_request::{AttestRequest, Measurement, Evidence};
use actix_web::{web, test::TestRequest};
use serde_json::json;

#[cfg(test)]
mod default_strategy_tests {
    use super::*;

    fn create_test_request() -> AttestRequest {
        AttestRequest {
            agent_version: Some("1.0.0".to_string()),
            measurements: vec![
                Measurement {
                    node_id: "test-node-1".to_string(),
                    nonce: Some("test-nonce".to_string()),
                    nonce_type: Some("challenge".to_string()),
                    token_fmt: Some("eat".to_string()),
                    attester_data: Some(json!({"key": "value"})),
                    evidences: vec![
                        Evidence {
                            attester_type: "tpm".to_string(),
                            evidence: json!({"quote": "test-quote"}),
                            policy_ids: Some(vec!["policy1".to_string()]),
                        }
                    ],
                }
            ],
        }
    }

    #[test]
    fn test_create_default_attestation_strategy_should_succeed() {
        let strategy = DefaultAttestationStrategy::new();
        
        // Verify that the strategy can be created successfully
        // This is a basic smoke test for the constructor
        let ptr = &strategy as *const _;
        assert!(ptr != std::ptr::null());
    }

    #[tokio::test]
    async fn test_execute_attestation_with_valid_request_should_create_future() {
        let strategy = DefaultAttestationStrategy::new();
        let request = create_test_request();
        let json_request = web::Json(request);
        
        // Create a test HTTP request
        let http_req = TestRequest::default()
            .insert_header(("User-Id", "test-user"))
            .to_http_request();
        
        // Test that the attest method can be called
        // Note: This test may fail due to missing dependencies or configuration,
        // but it tests the basic structure and interface
        let future = strategy.attest(&json_request, &http_req);
        
        // We can't easily test the full execution without proper setup,
        // but we can verify the future is created
        let ptr = &future as *const _;
        assert!(ptr != std::ptr::null());
    }

    #[tokio::test]
    async fn test_execute_attestation_without_user_id_should_handle_gracefully() {
        let strategy = DefaultAttestationStrategy::new();
        let request = create_test_request();
        let json_request = web::Json(request);
        
        // Create a test HTTP request without User-Id header
        let http_req = TestRequest::default().to_http_request();
        
        // Test that the attest method can handle missing User-Id header
        let future = strategy.attest(&json_request, &http_req);
        
        // Verify the future is created even without User-Id header
        let ptr = &future as *const _;
        assert!(ptr != std::ptr::null());
    }

    #[test]
    fn test_create_measurement_chain_should_initialize_properly() {
        let strategy = DefaultAttestationStrategy::new();
        
        // We can't directly test the private method, but we can test
        // that the strategy can be created, which internally uses this method
        // This is an indirect test of the create_measurement_chain functionality
        assert!(!std::ptr::eq(&strategy, std::ptr::null()));
    }
}